home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / Other Langs / MacPerl ƒ / Perl Source ƒ / Perl / icemalloc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-23  |  29.7 KB  |  1,221 lines  |  [TEXT/MPS ]

  1.  
  2. /*
  3. **
  4. ** Notice.
  5. **
  6. ** This source code was written by Tim Endres. time@ice.com
  7. ** Copyright 1988-1991 © By Tim Endres. All rights reserved.
  8. ** 8840 Main Street, Whitmore Lake, MI  48189
  9. **
  10. ** You may use this source code for any purpose you can dream
  11. ** of as long as this notice is never modified nor removed.
  12. **
  13. ** Please email me any improvements that you might make. Any
  14. ** reasonable form of diff (compare) on the files changes will
  15. ** do nicely. You can mail "time@ice.com". Thank you.
  16. **
  17. ** BTW: In case it is not obvious, do not #define DOCUMENTATION ;)
  18. **
  19. */
  20.  
  21.  
  22. #include <types.h>
  23. #include <memory.h>
  24.  
  25. #include "icemalloc.h"
  26.  
  27. #define mNEWPTR(size)            ( NewPtr ( (size) ) )
  28. #define mDISPOSPTR(ptr)            ( DisposPtr ( (ptr) ) )
  29.  
  30. #define DEBUG
  31.  
  32. #ifdef DOCUMENTATION
  33.  
  34.     malloc() will allocate "size" bytes from the default malloc pool.
  35.     
  36. #endif
  37.  
  38. char    *
  39. malloc ( size )
  40. u_long    size;
  41. {
  42. _mem_pool_ptr    pool;
  43.  
  44.     pool = _default_mem_pool;
  45.     if (pool == (_mem_pool_ptr)0)
  46.         return (char *)0;
  47.     
  48.     return _pool_malloc(pool, size);
  49.     }
  50.  
  51.  
  52. #ifdef DOCUMENTATION
  53.  
  54.     free() will free the memory occupied by the "ptr" allocated by malloc().
  55.     
  56. #endif
  57.  
  58. void free ( void * ptr )
  59. {
  60.     _pool_free((char *) ptr);
  61.     }
  62.  
  63. #ifdef DOCUMENTATION
  64.  
  65.     MN 15May93 realloc() tries to change the size of the memory pointed 
  66.     to by "ptr". No optimizations are attempted.
  67.     
  68. #endif
  69.  
  70. void *
  71. realloc ( old, size )
  72. void *     old;
  73. u_long    size;
  74. {
  75.     void *            nu;
  76.     
  77.     nu = malloc(size);
  78.     
  79.     if (!old || !nu)
  80.         return nu;
  81.     
  82.     memcpy(nu, old, size);
  83.     
  84.     free(old);
  85.     
  86.     return nu;
  87. }
  88.  
  89. #ifdef DOCUMENTATION
  90.  
  91.     set_default_pool() - given a pool id, this routine will make it the default
  92.     pool from which malloc() allocates memory.
  93.     
  94. #endif
  95.  
  96.  
  97. int set_default_pool ( id )
  98. int        id;
  99. {
  100. _mem_pool_ptr    pool, last;
  101.  
  102.     if (_default_mem_pool->id == id)
  103.         return 0;
  104.     
  105.     last = _default_mem_pool;
  106.     pool = _default_mem_pool->next;
  107.     for ( ; pool != (_mem_pool_ptr)0 ; pool = pool->next) {
  108.         if (pool->id == id) {
  109.             last->next = pool->next;
  110.             pool->next = _default_mem_pool;
  111.             _default_mem_pool = pool;
  112.             return 0;
  113.             }
  114.         }
  115.     
  116.     return -1;
  117.     }
  118.  
  119.  
  120. #ifdef DOCUMENTATION
  121.  
  122.     new_malloc_pool() creates a new pool from which memory can be malloc()-ed.
  123.     
  124. #endif
  125.  
  126. _mem_pool_ptr
  127. new_malloc_pool ( id, pref_blk_size )
  128. int        id;
  129. u_long    pref_blk_size;
  130. {
  131. _mem_pool_ptr    new_pool;
  132.  
  133.     new_pool = find_pool(id);
  134.     if (new_pool != NULL)            /* ? Is this the best choice? Its not ID-able */
  135.         return new_pool;
  136.  
  137.     new_pool = (_mem_pool_ptr) mNEWPTR( sizeof(_mem_pool) );
  138.     if (new_pool == (_mem_pool_ptr)0)
  139.         return new_pool;
  140.     
  141.     new_pool->id = id;                            /* The pool's ID. */
  142.     new_pool->pref_blk_size = pref_blk_size;    /* The preferred size of new blks. */
  143.     new_pool->blk_list = NULL;                    /* The list of blocks in the pool. */
  144.     
  145.     /* The next two lines insert right after the default, so we don't change it. */
  146.     new_pool->next = _mem_pool_forest->next;
  147.     _mem_pool_forest->next = new_pool;
  148.  
  149. #ifdef _PM_STATS
  150.     new_pool->total_memory = 0;            /* The total allocated memory by this pool */
  151.     new_pool->total_storage = 0;        /* The total malloc-able storage in this pool */
  152.     new_pool->total_malloc = 0;            /* The total malloc-ed storage not freed. */
  153.     new_pool->max_blk_size = 0;            /* The maximum block size allocated. */
  154.     new_pool->ave_req_size = 0.0;        /* The ave allocated request size */
  155.     new_pool->ave_req_total = 0;        /* The total requests in the average. */
  156.     new_pool->ave_blk_size = 0.0;        /* The ave sallocated blk size */
  157.     new_pool->ave_blk_total = 0;        /* The total blks in the average. */
  158. #endif
  159.  
  160.     return new_pool;
  161.     }
  162.  
  163.  
  164. #ifdef DOCUMENTATION
  165.  
  166.     find_pool() will find the pool with the given "id" and return its pointer.
  167.     
  168. #endif
  169.  
  170. _mem_pool_ptr
  171. find_pool ( id )
  172. int        id;
  173. {
  174. _mem_pool_ptr    pool;
  175.  
  176.     for (pool = _mem_pool_forest ; pool != (_mem_pool_ptr)0 ; pool = pool->next) {
  177.         if (pool->id == id)
  178.             break;
  179.         }
  180.         
  181.     return pool;
  182.     }
  183.  
  184.  
  185. #ifdef DOCUMENTATION
  186.  
  187.     free_pool_memory() this will free and *release* all memory occupied by the
  188.     pool but not free the pool, letting you allocate some more.
  189.     
  190. #endif
  191.  
  192. free_pool_memory ( id )
  193. int        id;
  194. {
  195. _mem_pool_ptr    pool;
  196. _mem_blk_ptr    blk, nextblk;
  197.  
  198.     pool = find_pool(id);
  199.     if (pool == NULL)
  200.         return -1;
  201.     
  202.     for ( blk = pool->blk_list ; blk != (_mem_blk_ptr)0 ; ) {
  203.         nextblk = blk->next;
  204.         DPRINTF(3, ("pool_find_free_blk() Freeing Block x%lx from pool #%d!\n",
  205.                         blk, blk->pool->id));
  206. #ifdef _PM_STATS
  207.         pool->total_memory -= sizeof(_mem_blk) + blk->size;
  208.         pool->total_storage -= blk->size;
  209. #endif
  210.         mDISPOSPTR((Ptr)blk->memory);
  211.         mDISPOSPTR((Ptr)blk);
  212.  
  213.         blk = nextblk;
  214.         }
  215.  
  216.     pool->blk_list = NULL;
  217.     
  218.     return 0;
  219.     }
  220.  
  221.  
  222. #ifdef DOCUMENTATION
  223.  
  224.     free_pool() will free the pool's memory *and* free the pool (removing
  225.     it from the pool list) releasing all memory back to the heap.
  226.     
  227. #endif
  228.  
  229. free_pool ( id )
  230. int        id;
  231. {
  232. _mem_pool_ptr    pool;
  233.  
  234.     if (free_pool_memory(id) == -1)
  235.         return -1;
  236.     
  237.     pool = find_pool(id);
  238.     if (pool == NULL)
  239.         return -1;
  240.     
  241.     mDISPOSPTR((Ptr)pool);
  242.     
  243.     return 0;
  244.     }
  245.  
  246.  
  247. #ifdef DOCUMENTATION
  248.  
  249.     _pool_malloc() does the low level malloc() work in a specified pool.
  250.     
  251. #endif
  252.  
  253. char    *
  254. _pool_malloc(pool, size)
  255. _mem_pool_ptr    pool;
  256. u_long            size;
  257. {
  258. _mem_blk_ptr        blk;
  259. _mem_ptr_hdr_ptr    hdr = (_mem_ptr_hdr_ptr)0, freehdr;
  260. u_long                freesize, size_req;
  261. char                *ptr = (char *)0;
  262.  
  263.     DPRINTF(5, ("_pool_malloc() request of %ld bytes in pool #%d [x%lx]\n",
  264.                 size, pool->id, pool));
  265.  
  266.     size_req = (size < _PM_MIN_ALLOC_SIZE) ? _PM_MIN_ALLOC_SIZE : size;
  267.     size_req = INT_ALIGN(size_req, ALIGNMENT);
  268.  
  269. #ifdef _PM_STATS
  270.     pool->ave_req_size = ( ( (pool->ave_req_size * (float)pool->ave_req_total) + (float)size_req )
  271.                             / (float)(pool->ave_req_total + 1) );
  272.     pool->ave_req_total++;
  273. #endif
  274.  
  275.     blk = pool->blk_list;
  276.     if (blk == NULL) {
  277.         /* No blocks in pool, allocate one... */
  278.         blk = _pool_new_blk(pool, size_req);
  279.         }
  280.     else {
  281.         blk = _pool_find_free_blk(pool, size_req, &hdr);
  282.  
  283.         if (blk == (_mem_blk_ptr)0 || hdr == (_mem_ptr_hdr_ptr)0) {
  284.             /* No blocks that can support this size... */
  285.             blk = _pool_new_blk(pool, size_req);
  286.             }
  287.         else
  288.             DPRINTF(5, ("_pool_malloc() found free: blk x%lx hdr x%lx\n",
  289.                         blk, hdr));
  290.         }
  291.     
  292.     if (blk != (_mem_blk_ptr)0) {
  293.         /* Determine the pointer's location, establish, return. */
  294.         if (hdr == (_mem_ptr_hdr_ptr)0) {
  295.             hdr = (_mem_ptr_hdr_ptr) blk->memory;
  296.             DPRINTF(5, ("_pool_malloc() header of new blk blk->memory x%lx\n", blk->memory));
  297.             }
  298.         
  299.         DPRINTF(5, ("_pool_malloc() free hdr x%lx size %ld\n", hdr, GET_PTR_SIZE(hdr)));
  300.         if (hdr != (_mem_ptr_hdr_ptr)0) {
  301.             ptr = (char *)hdr + sizeof(_mem_ptr_hdr);
  302.             
  303.             if (size_req < GET_PTR_SIZE(hdr)) {
  304.                 /* Split this free block... */
  305.                 DPRINTF(5, ("_pool_malloc() split hdr x%lx into %ld used and %ld free\n",
  306.                             hdr, size_req, GET_PTR_SIZE(hdr) - (size_req + sizeof(_mem_ptr_hdr))));
  307.  
  308.                 freehdr = (_mem_ptr_hdr_ptr)
  309.                             ( (char *)hdr + sizeof(_mem_ptr_hdr) + size_req );
  310.                 freesize = GET_PTR_SIZE(hdr) - (sizeof(_mem_ptr_hdr) + size_req);
  311.                 bzero(freehdr, sizeof(_mem_ptr_hdr));
  312.                 SET_PTR_FREE(freehdr);
  313.                 SET_PTR_SIZE(freehdr, freesize);
  314.                 blk->max_free -= sizeof(_mem_ptr_hdr);
  315.                 }
  316.  
  317. #ifdef _PM_STATS    
  318.             pool->total_malloc += size_req;
  319. #endif
  320.  
  321.             blk->max_free -= size_req;
  322.             SET_PTR_USED(hdr);
  323.             SET_PTR_SIZE(hdr, size_req);
  324.             bzero(ptr, size_req);        /* Programmer's expect malloc() to zero. */
  325.             }
  326.         else {
  327.             /* ERROR: This should not happen!!! */
  328.             DPRINTF(1, ("ERROR: pool_malloc() could not get block's free hdr ptr\n"));
  329.             DACTION(2, { list_pool_forest(NULL); });
  330.             }
  331.         }
  332.     else {
  333.         /* ERROR, no block, no memory. */
  334.         DPRINTF(1, ("ERROR: pool_malloc() could not get a block\n"));
  335.         DACTION(2, { list_pool_forest(NULL); });
  336.         }
  337.     
  338.     DPRINTF(5, ("_pool_malloc() returning ptr x%lx\n", ptr));
  339.     return ptr;
  340.     }
  341.  
  342. #ifdef DOCUMENTATION
  343.  
  344.     _pool_free() does the low level work of a free().
  345.     
  346. #endif
  347.  
  348. _pool_free ( ptr )
  349. char    *ptr;
  350. {
  351. _mem_pool_ptr        pool;
  352. _mem_blk_ptr        blk;
  353. _mem_ptr_hdr_ptr    hdr, adjhdr, limit;
  354. int                    result = 0;
  355. u_long                ptr_size, new_size;
  356.  
  357.     if (ptr == (char *)0) {
  358.         /* WHOAH! NULL Pointers... */
  359.         DPRINTF(1, ("_pool_free() ptr NULL!"));
  360.         return -1;
  361.         }
  362.     
  363.     if ( ( (u_long)ptr & 1 ) != 0 ) {
  364.         /* WHOAH! ODD Pointers... */
  365.         DPRINTF(1, ("_pool_free() ptr ODD!"));
  366.         return -1;
  367.         }
  368.     
  369.     DPRINTF(5, ("_pool_free() free ptr x%lx\n", ptr));
  370.  
  371.     blk = _pool_find_ptr_blk(ptr);
  372.     
  373.     if (blk == (_mem_blk_ptr)0) {
  374.         /* We could not find this thing's blk! BUG!!! */
  375.         DPRINTF(1, ("ERROR: free(x%lx) could not find ptr's blk\n", ptr));
  376.         DACTION(2, { list_pool_forest(NULL); });
  377.         result = -1;
  378.         }
  379.     else {
  380.         /*
  381.         ** Now, if it is adjacent to free memory, combine.
  382.         ** NOTE: We only do this because it is SO DAMN CHEAP!!!!!
  383.         */
  384.  
  385.         /* Delay these assigns til we know ptr is good. (now) */
  386.         hdr = (_mem_ptr_hdr_ptr) ( (u_long)ptr - sizeof(_mem_ptr_hdr) );
  387.         ptr_size = GET_PTR_SIZE(hdr);
  388.  
  389.         DPRINTF(5, ("_pool_free() free hdr x%lx size %ld flags x%02x in blk x%lx\n",
  390.                     hdr, ptr_size, GET_PTR_FLAGS(hdr), blk));
  391.     
  392.         pool = blk->pool;
  393.         SET_PTR_FREE(hdr);
  394.         blk->max_free += ptr_size;
  395.         
  396.         adjhdr = (_mem_ptr_hdr_ptr)
  397.                     ( (char *)hdr + GET_PTR_SIZE(hdr) +
  398.                       sizeof(_mem_ptr_hdr) );
  399.         limit = (_mem_ptr_hdr_ptr) ((char *)blk->memory + blk->size);
  400.         
  401.         if (adjhdr < limit && IS_PTR_FREE(adjhdr)) {
  402.             DPRINTF(5, ("_pool_free() merging hdr x%lx with freehdr x%lx\n", hdr, adjhdr));
  403.             
  404.             new_size =    GET_PTR_SIZE(hdr) +
  405.                         GET_PTR_SIZE(adjhdr) +
  406.                         sizeof(_mem_ptr_hdr);
  407.  
  408.             DPRINTF(5, ("_pool_free() merged hdr new_size %ld\n", new_size));
  409.             SET_PTR_SIZE(hdr, new_size);
  410.             blk->max_free += sizeof(_mem_ptr_hdr);
  411.             }    /* is adjacent free ? */
  412.         
  413. #ifdef _PM_STATS    
  414.         pool->total_malloc -= ptr_size;
  415. #endif
  416.  
  417. #ifdef _PM_DYNAMIC_FREE
  418.         if (block_is_freed(blk)) {
  419.             /* This blk is free-ed ... */
  420.             _mem_blk_ptr    tmpblk;
  421.  
  422.             if (blk == blk->pool->blk_list) {
  423.                 blk->pool->blk_list = blk->next;
  424.                 }
  425.             else {
  426.                 tmpblk = blk->pool->blk_list;
  427.                 while (tmpblk != (_mem_blk_ptr)0) {
  428.                     if (tmpblk->next == blk) {
  429.                         tmpblk->next = blk->next;
  430.                         break;
  431.                         }
  432.                     else
  433.                         tmpblk = tmpblk->next;
  434.                     }
  435.                 if (tmpblk == (_mem_blk_ptr)0)
  436.                     DPRINTF(1, ("ERROR: could not free blk x%lx from list!\n", blk));
  437.                 }
  438.             
  439.             DPRINTF(3, ("_pool_free() Freeing Block x%lx from pool #%d!\n",
  440.                         blk, blk->pool->id));
  441. #ifdef _PM_STATS
  442.             pool->total_memory -= sizeof(_mem_blk) + blk->size;
  443.             pool->total_storage -= blk->size;
  444. #endif
  445.             mDISPOSPTR((Ptr)blk->memory);
  446.             mDISPOSPTR((Ptr)blk);
  447.             }    /* if (block_is_freed(blk)) */
  448. #endif _PM_DYNAMIC_FREE
  449.  
  450.         result = 0;
  451.         }    /* else we found the block containing the ptr. */
  452.     
  453.     return result;
  454.     }
  455.  
  456. #ifdef DOCUMENTATION
  457.  
  458.     block_is_freed() determines if all memory in a given block is free.
  459.     
  460. #endif
  461.  
  462. block_is_freed(blk)
  463. _mem_blk_ptr    blk;
  464. {
  465. int            freed = 1;
  466. _mem_ptr_hdr_ptr    loophdr, limit;
  467.  
  468. /*
  469. ** This loop is not as expensive as you might think, since most of the
  470. ** time we've "merged" into few "ptrs", and in allocated cases we will
  471. ** break out of the loop almost immediately.
  472. */
  473.  
  474.     if (blk != NULL) {
  475.         loophdr = (_mem_ptr_hdr_ptr) blk->memory;
  476.         limit = (_mem_ptr_hdr_ptr) ((char *)blk->memory + blk->size);
  477.         while (loophdr < limit) {
  478.             if (! IS_PTR_FREE(loophdr)) {
  479.                 freed = 0;
  480.                 break;
  481.                 }
  482.             
  483.             loophdr = (_mem_ptr_hdr_ptr)
  484.                         ((char *)loophdr + GET_PTR_SIZE(loophdr) + sizeof(_mem_ptr_hdr));
  485.             }
  486.         }
  487.     else
  488.         freed = 0;    /* ? Or is it really free? */
  489.     
  490.     return freed;
  491.     }
  492.  
  493.  
  494. #ifdef DOCUMENTATION
  495.  
  496.     _pool_new_blk() allocate a new memory block to a pool. This is called
  497.     by the low level malloc() code when new memory is needed.
  498.     
  499. #endif
  500.  
  501. _mem_blk_ptr
  502. _pool_new_blk(pool, size_req)
  503. _mem_pool_ptr    pool;
  504. u_long            size_req;    /* size required */
  505. {
  506. u_long                blk_size;
  507. _mem_blk_ptr        new_blk;
  508. _mem_ptr_hdr_ptr    hdr;
  509.  
  510.     DPRINTF(5, ("_pool_new_blk() req_size %ld pool #%d [x%lx]\n", size_req, pool->id, pool));
  511.  
  512.     if ((size_req + sizeof(_mem_ptr_hdr)) > pool->pref_blk_size) {
  513.         blk_size = ((size_req / pool->pref_blk_size) + 1) * pool->pref_blk_size;
  514. #ifdef _PM_STATS
  515.         if (blk_size > pool->max_blk_size)
  516.             pool->max_blk_size = blk_size;
  517. #endif
  518.         }
  519.     else
  520.         blk_size = pool->pref_blk_size;
  521.     
  522.     blk_size = INT_ALIGN(blk_size, ALIGNMENT);
  523.     
  524. #ifdef _PM_STATS
  525.     pool->ave_blk_size = ( ( (pool->ave_blk_size * (float)pool->ave_blk_total) + (float)blk_size )
  526.                             / (float)(pool->ave_blk_total + 1) );
  527.     pool->ave_blk_total++;
  528. #endif
  529.  
  530.     new_blk = (_mem_blk_ptr) mNEWPTR(sizeof(_mem_blk));
  531.     if (new_blk == (_mem_blk_ptr)0)
  532.         return new_blk;
  533.     
  534.     /*
  535.     ** NOTE: We assume here that mNEWPTR() gives us proper alignment.
  536.     */
  537.     new_blk->memory = (char *) mNEWPTR(blk_size);
  538. #ifdef NEVER_DEFINED
  539.     if (new_blk->memory == (char *)0) {
  540.         /* Attempt to handle the request only. */
  541.         blk_size = size_req + sizeof(_mem_ptr_hdr);
  542.         blk_size = INT_ALIGN(blk_size, ALIGNMENT);
  543.         new_blk->memory = (char *) mNEWPTR(blk_size);
  544.         }
  545. #endif
  546.     
  547.     if (new_blk->memory == (char *)0) {
  548.         mDISPOSPTR((Ptr)new_blk);
  549.         DPRINTF(10, ("_pool_new_blk(pool:x%lx, size:%ld) Out of memory.\n", pool, size_req));
  550.         return (_mem_blk_ptr)0;
  551.         }
  552.     
  553. #ifdef _PM_STATS
  554.     pool->total_memory += sizeof(_mem_blk) + blk_size;
  555.     pool->total_storage += blk_size;
  556. #endif
  557.  
  558.     new_blk->pool = pool;
  559.     new_blk->size = blk_size;
  560.     new_blk->max_free = blk_size - sizeof(_mem_ptr_hdr);
  561.     
  562.     /* Add to the block list. */
  563.     new_blk->next = pool->blk_list;
  564.     pool->blk_list = new_blk;
  565.     
  566.     hdr = (_mem_ptr_hdr_ptr) new_blk->memory;
  567.     bzero(hdr, sizeof(_mem_ptr_hdr));
  568.     
  569.     SET_PTR_FREE(hdr);
  570.     SET_PTR_SIZE(hdr, ( blk_size - sizeof(_mem_ptr_hdr) ) );
  571.     
  572.     DPRINTF(5, ("_pool_new_blk() new blk x%lx size %ld memory x%lx pool #%d [x%lx]\n",
  573.             new_blk, new_blk->size, new_blk->memory, pool->id, pool));
  574.     return new_blk;
  575.     }
  576.     
  577.  
  578. #ifdef DOCUMENTATION
  579.  
  580.     _pool_find_free_blk() looks for a block in the pool with enough free memory
  581.     to allocate the "size_req" bytes.
  582.     
  583. #endif
  584.  
  585. _mem_blk_ptr
  586. _pool_find_free_blk(pool, size_req, hdr_ptr)
  587. _mem_pool_ptr        pool;
  588. u_long                size_req;    /* size required */
  589. _mem_ptr_hdr_ptr    *hdr_ptr;
  590. {
  591. _mem_blk_ptr        blk, use_this_blk;
  592. _mem_ptr_hdr_ptr    loophdr, limit;
  593. long                hdrsize, max_size;
  594.  
  595. #ifdef _PM_DYNAMIC_MERGING
  596. _mem_ptr_hdr_ptr    lasthdr, nexthdr, blkhdr;
  597. long                lastsize, nextsize;
  598. #endif _PM_DYNAMIC_MERGING
  599.  
  600.     blk = pool->blk_list;
  601.     max_size = 0x3FFFFFFF;
  602.     for (use_this_blk=NULL; blk != (_mem_blk_ptr)0 ; blk=blk->next) {
  603.         if (blk->max_free >= size_req) {
  604.             if (use_this_blk == NULL) {
  605.                 use_this_blk = blk;
  606.                 max_size = blk->size;
  607.                 }
  608.             else if (blk->size < max_size) {
  609.                 use_this_blk = blk;
  610.                 max_size = blk->size;
  611.                 }
  612.             }
  613.         }
  614.     
  615.     blk = use_this_blk;
  616.     if (blk != NULL) {
  617.         loophdr = (_mem_ptr_hdr_ptr) blk->memory;
  618.         limit = (_mem_ptr_hdr_ptr) ((char *)blk->memory + blk->size);
  619. #ifdef _PM_DYNAMIC_MERGING
  620.         lasthdr = (_mem_ptr_hdr_ptr)0;
  621. #endif _PM_DYNAMIC_MERGING
  622.         while (loophdr < limit) {
  623.             if (IS_PTR_FREE(loophdr)) {
  624.                 hdrsize = GET_PTR_SIZE(loophdr);
  625.                 if (hdrsize >= size_req) {
  626.                     DPRINTF(5, ("pool_find_free_blk() Found blk x%lx hdr x%lx pool #%d [x%lx]\n",
  627.                                 blk, loophdr, pool->id, pool));
  628.                     
  629.                     *hdr_ptr = loophdr;
  630.                     return blk;
  631.                     }
  632.  
  633. #ifdef _PM_DYNAMIC_MERGING
  634.                 else {
  635.                     nexthdr = (_mem_ptr_hdr_ptr)
  636.                                 ( (char *)loophdr + hdrsize + sizeof(_mem_ptr_hdr) );
  637.                     if (nexthdr < limit) {
  638.                         if (IS_PTR_FREE(nexthdr)) {
  639.                             nextsize = GET_PTR_SIZE(nexthdr);
  640.                             blk->max_free += sizeof(_mem_ptr_hdr);    /* We're gonna merge... */
  641.                             if ((nextsize + hdrsize + sizeof(_mem_ptr_hdr)) >= size_req) {
  642.                                 DPRINTF(3, ("pool_find_free_blk() F-Merge blk x%lx hdr1 x%lx hdr2 x%lx \n",
  643.                                             blk, loophdr, nexthdr));
  644.                                 
  645.                                 hdrsize = nextsize + hdrsize + sizeof(_mem_ptr_hdr);
  646.                                 SET_PTR_SIZE(loophdr, hdrsize);
  647.                                 *hdr_ptr = loophdr;
  648.                                 return blk;
  649.                                 }
  650.                             else {
  651.                                 /* OK, so merge anyways... */
  652.                                 hdrsize = nextsize + hdrsize + sizeof(_mem_ptr_hdr);
  653.                                 SET_PTR_SIZE(loophdr, hdrsize);
  654.                                 }
  655.                             }
  656.                         }
  657.                     if (lasthdr != (_mem_ptr_hdr_ptr)0) {
  658.                         if (IS_PTR_FREE(lasthdr)) {
  659.                             lastsize = GET_PTR_SIZE(lasthdr);
  660.                             blk->max_free += sizeof(_mem_ptr_hdr);    /* We're gonna merge... */
  661.                             if ((lastsize + hdrsize + sizeof(_mem_ptr_hdr)) >= size_req) {
  662.                                 DPRINTF(3, ("pool_find_free_blk() R-Merge blk x%lx hdr1 x%lx hdr2 x%lx \n",
  663.                                             blk, lasthdr, loophdr));
  664.                                 
  665.                                 hdrsize = lastsize + hdrsize + sizeof(_mem_ptr_hdr);
  666.                                 SET_PTR_SIZE(lasthdr, hdrsize);
  667.                                 *hdr_ptr = lasthdr;
  668.                                 return blk;
  669.                                 }
  670.                             else {
  671.                                 /* OK, so merge anyways... */
  672.                                 hdrsize = lastsize + hdrsize + sizeof(_mem_ptr_hdr);
  673.                                 SET_PTR_SIZE(lasthdr, hdrsize);
  674.                                 }
  675.                             loophdr = lasthdr;
  676.                             lasthdr = (_mem_ptr_hdr_ptr)0;
  677.                             }
  678.                         }
  679. #ifdef _PM_DYNAMIC_FREE
  680.                     blkhdr = (_mem_ptr_hdr_ptr)blk->memory;
  681.                     if (IS_PTR_FREE(blkhdr)) {
  682.                         if ((GET_PTR_SIZE(blkhdr) + sizeof(_mem_ptr_hdr)) == blk->size) {
  683.                             /* This blk is free-ed ... */
  684.                             
  685.                             _mem_blk_ptr    tmpblk, next;
  686.             
  687.                             if (blk == blk->pool->blk_list) {
  688.                                 blk->pool->blk_list = next = blk->next;
  689.                                 }
  690.                             else {
  691.                                 tmpblk = blk->pool->blk_list;
  692.                                 while (tmpblk != (_mem_blk_ptr)0) {
  693.                                     if (tmpblk->next == blk) {
  694.                                         tmpblk->next = next = blk->next;
  695.                                         break;
  696.                                         }
  697.                                     else
  698.                                         tmpblk = tmpblk->next;
  699.                                     }
  700.                                 if (tmpblk == (_mem_blk_ptr)0)
  701.                                     DPRINTF(1, ("pool_find_free_blk() ERROR: could not free blk x%lx from list!\n", blk));
  702.                                 }
  703.                             
  704.                             DPRINTF(3, ("pool_find_free_blk() Freeing Block x%lx from pool #%d!\n",
  705.                                         blk, blk->pool->id));
  706. #ifdef _PM_STATS
  707.                             pool->total_memory -= sizeof(_mem_blk) + blk->size;
  708.                             pool->total_storage -= blk->size;
  709. #endif
  710.                             mDISPOSPTR((Ptr)blk->memory);
  711.                             mDISPOSPTR((Ptr)blk);
  712.                             blk = next;
  713.                             break;    /* The while (hdr) loop, into while (blk) loop */
  714.                             }
  715.                         }    /* if (IS_PTR_FREE(blkhdr)) */
  716. #endif _PM_DYNAMIC_FREE
  717.  
  718.                     }
  719. #endif _PM_DYNAMIC_MERGING
  720.  
  721.                 }
  722. #ifdef _PM_DYNAMIC_MERGING
  723.             lasthdr = loophdr;
  724. #endif _PM_DYNAMIC_MERGING
  725.             loophdr = (_mem_ptr_hdr_ptr)
  726.                         ((char *)loophdr + GET_PTR_SIZE(loophdr) + sizeof(_mem_ptr_hdr));
  727.             }
  728.         }
  729.     
  730.     *hdr_ptr = (_mem_ptr_hdr_ptr)0;
  731.     return blk;
  732.     }
  733.     
  734.  
  735. #ifdef DOCUMENTATION
  736.  
  737.     _pool_find_ptr_blk() finds the block containing this pointer in "ptr".
  738.     
  739. #endif
  740.  
  741. _mem_blk_ptr
  742. _pool_find_ptr_blk(ptr)
  743. char    *ptr;
  744. {
  745. _mem_pool_ptr    pool;
  746. _mem_blk_ptr    blk;
  747.  
  748.     /*
  749.     ** Since the default list is stored at the front of the forest list,
  750.     ** we inherently search the default forest first. Nice.
  751.     */
  752.     pool = _mem_pool_forest;
  753.     
  754.     while (pool != (_mem_pool_ptr)0) {
  755.         blk = pool->blk_list;
  756.         
  757.         while (blk != (_mem_blk_ptr)0) {
  758.             if ( ( ptr >= blk->memory ) &&
  759.                  ( ptr <= ((char *)blk->memory + blk->size) ) )
  760.                 return blk;
  761.             else
  762.                 blk = blk->next;
  763.             }
  764.         
  765.         pool = pool->next;
  766.         }
  767.     
  768.     return (_mem_blk_ptr)0;
  769.     }
  770.  
  771.  
  772. #ifdef DOCUMENTATION
  773.  
  774.     merge_free_list() runs the routine to merge and "release" any free-ed
  775.     blocks back into the heap.
  776.     
  777. #endif
  778.  
  779. merge_free_list()
  780. {
  781.     return _pool_free_list_merge(_default_mem_pool);
  782.     }
  783.  
  784.  
  785. #ifdef DOCUMENTATION
  786.  
  787.     _pool_free_list_merge() will merge and "release" any free-ed blocks
  788.     back into the heap.
  789.     
  790. #endif
  791.  
  792. _pool_free_list_merge(pool)
  793. _mem_pool_ptr        pool;
  794. {
  795. _mem_blk_ptr        blk, nextblk;
  796. _mem_ptr_hdr_ptr    loophdr, limit, nexthdr, blkhdr;
  797. int                    result = 0;
  798. long                hdrsize, nextsize;
  799.  
  800.     blk = pool->blk_list;
  801.     while (blk != (_mem_blk_ptr)0) {
  802.         loophdr = blkhdr = (_mem_ptr_hdr_ptr)blk->memory;
  803.         limit = (_mem_ptr_hdr_ptr) ((char *)blk->memory + blk->size);
  804.         while (loophdr < limit) {
  805.             if (IS_PTR_FREE(loophdr)) {
  806.                 hdrsize = GET_PTR_SIZE(loophdr);
  807.                 nexthdr = (_mem_ptr_hdr_ptr)
  808.                             ( (char *)loophdr + hdrsize + sizeof(_mem_ptr_hdr) );
  809.                 /* Now loop and merge free ptr's til used one is hit... */
  810.                 while (nexthdr < limit) {
  811.                     if (IS_PTR_FREE(nexthdr)) {
  812.                         nextsize = GET_PTR_SIZE(nexthdr);
  813.                         blk->max_free += sizeof(_mem_ptr_hdr);    /* We're gonna merge... */
  814.                         hdrsize = nextsize + hdrsize + sizeof(_mem_ptr_hdr);
  815.                         SET_PTR_SIZE(loophdr, hdrsize);
  816.                         nexthdr = (_mem_ptr_hdr_ptr)
  817.                                     ( (char *)loophdr + hdrsize + sizeof(_mem_ptr_hdr) );
  818.                         }
  819.                     else
  820.                         break;
  821.                     }
  822.                 }
  823.             
  824.             loophdr = (_mem_ptr_hdr_ptr)
  825.                         ((char *)loophdr + GET_PTR_SIZE(loophdr) + sizeof(_mem_ptr_hdr));
  826.             }
  827.  
  828.         /* Get next block now, so _PM_DYNAMIC_FREE can modify blk as desired */
  829.         nextblk = blk->next;
  830.  
  831. #ifdef _PM_DYNAMIC_FREE
  832.         if (IS_PTR_FREE(blkhdr)) {
  833.             if ((GET_PTR_SIZE(blkhdr) + sizeof(_mem_ptr_hdr)) == blk->size) {
  834.                 /* This blk is free-ed ... */
  835.                 _mem_blk_ptr    tmpblk;
  836.  
  837.                 if (blk == blk->pool->blk_list) {
  838.                     blk->pool->blk_list = blk->next;
  839.                     }
  840.                 else {
  841.                     tmpblk = blk->pool->blk_list;
  842.                     while (tmpblk != (_mem_blk_ptr)0) {
  843.                         if (tmpblk->next == blk) {
  844.                             tmpblk->next = blk->next;
  845.                             break;
  846.                             }
  847.                         else
  848.                             tmpblk = tmpblk->next;
  849.                         }
  850.                     if (tmpblk == (_mem_blk_ptr)0)
  851.                         DPRINTF(1, ("pool_find_free_blk() ERROR: could not free blk x%lx from list!\n", blk));
  852.                     }
  853.                 
  854.                 DPRINTF(3, ("pool_find_free_blk() Freeing Block x%lx from pool #%d!\n",
  855.                             blk, blk->pool->id));
  856. #ifdef _PM_STATS
  857.                 pool->total_memory -= sizeof(_mem_blk) + blk->size;
  858.                 pool->total_storage -= blk->size;
  859. #endif
  860.                 result += blk->size + sizeof(_mem_blk);
  861.                 mDISPOSPTR((Ptr)blk->memory);
  862.                 mDISPOSPTR((Ptr)blk);
  863.                 }
  864.             
  865.             }    /* if (IS_PTR_FREE(blkhdr)) */
  866. #endif _PM_DYNAMIC_FREE
  867.         
  868.         blk = nextblk;
  869.         }
  870.     
  871.     return result;
  872.     }
  873.     
  874.  
  875. #ifdef DOCUMENTATION
  876.  
  877.     get_malloc_stats() return several statistics about the default heap.
  878.     
  879. #endif
  880.  
  881. get_malloc_stats(total_memory, total_free, total_malloc)
  882. long        *total_memory;
  883. long        *total_free;
  884. long        *total_malloc;
  885. {
  886. _mem_pool_ptr        pool;
  887. _mem_blk_ptr        blk;
  888. _mem_ptr_hdr_ptr    hdr, limit;
  889. u_long                total_size, used_space, free_space;
  890. u_long                ptr_size;
  891.  
  892.     pool = _default_mem_pool;
  893.     blk = pool->blk_list;
  894.     total_size = used_space = free_space = 0;
  895.     for ( ; blk != (_mem_blk_ptr)0; ) {
  896.         hdr = (_mem_ptr_hdr_ptr) blk->memory;
  897.         limit = (_mem_ptr_hdr_ptr) ((char *)blk->memory + blk->size);
  898.         total_size += blk->size;
  899.         for ( ; hdr && hdr < limit; ) {
  900.             ptr_size = GET_PTR_SIZE(hdr);
  901.             if (IS_PTR_FREE(hdr))
  902.                 free_space += ptr_size;
  903.             else
  904.                 used_space += ptr_size;
  905.             
  906.             hdr = (_mem_ptr_hdr_ptr)
  907.                     ( (char *)hdr + GET_PTR_SIZE(hdr) + sizeof(_mem_ptr_hdr) );
  908.             }
  909.         
  910.         blk = blk->next;
  911.         }
  912.     
  913.     *total_memory = total_size;
  914.     *total_free = free_space;
  915.     *total_malloc = used_space;
  916.     }
  917.  
  918. #ifdef DEBUG
  919.  
  920. #include <stdio.h>
  921.  
  922. char    temp_str[512];
  923.  
  924. list_all_pool_stats(file)
  925. FILE    *file;
  926. {
  927. _mem_pool_ptr        pool;
  928.  
  929.     pool = _mem_pool_forest;
  930.     
  931.     while (pool != (_mem_pool_ptr)0) {
  932.         
  933.         list_pool_stats(file, pool);
  934.  
  935.         pool = pool->next;
  936.         }
  937.     
  938.     }
  939.  
  940.  
  941. list_pool_stats(file, pool)
  942. FILE    *file;
  943. _mem_pool_ptr        pool;
  944. {
  945. _mem_blk_ptr        blk;
  946. _mem_ptr_hdr_ptr    hdr, limit;
  947. int                    i, j;
  948. int                    num_used_hdrs, num_free_hdrs;
  949. u_long                used_hdr_space, free_hdr_space;
  950. u_long                ptr_size, max_free_size, max_used_size;
  951. float                ave_used_size, ave_free_size, frag_ratio;
  952.  
  953.     if (file == (FILE *)0) {
  954.         file = stdout;
  955.         }
  956.     
  957.     fprintf(file, "POOL STATISTICS FOR ID#%d @ x%lx blk_list x%lx pref_blk_size %ld\n",
  958.             pool->id, pool, pool->blk_list, pool->pref_blk_size);
  959.  
  960. #ifdef _PM_STATS
  961.     fprintf(file, "\tMEMORY: Total memory %ld Total ptr space %ld Currently malloc-ed %ld\n",
  962.             pool->total_memory, pool->total_storage, pool->total_malloc);
  963.     fprintf(file, "\tREQUESTS: Ave req size %f Total reqs %ld Total size reqs %f\n",
  964.             pool->ave_req_size, pool->ave_req_total, 
  965.             (float) (pool->ave_req_size * (float)pool->ave_req_total));
  966.     fprintf(file, "\tBLOCKS: Max block size %ld Ave block size %f\n",
  967.             pool->max_blk_size, pool->ave_blk_size);
  968.     fprintf(file, "\tBLOCKS: Total ave blocks %ld Total ave size %f\n",
  969.             pool->ave_blk_total,(float) (pool->ave_blk_size * (float)pool->ave_blk_total));
  970. #endif
  971.  
  972.         fprintf(file, "POOL BLOCK STATISTICS:\n");
  973.         
  974.         blk = pool->blk_list;
  975.         for (i=0; blk != (_mem_blk_ptr)0; i++) {
  976.             hdr = (_mem_ptr_hdr_ptr) blk->memory;
  977.             limit = (_mem_ptr_hdr_ptr) ((char *)blk->memory + blk->size);
  978.             num_used_hdrs = num_free_hdrs = 0;
  979.             used_hdr_space = free_hdr_space = 0;
  980.             max_free_size = max_used_size = 0;
  981.             for (j=0; hdr && hdr < limit; j++) {
  982.                 ptr_size = GET_PTR_SIZE(hdr);
  983.                 if (IS_PTR_FREE(hdr)) {
  984.                     num_free_hdrs++;
  985.                     free_hdr_space += ptr_size;
  986.                     if (ptr_size > max_free_size)
  987.                         max_free_size = ptr_size;
  988.                     }
  989.                 else {
  990.                     num_used_hdrs++;
  991.                     used_hdr_space += ptr_size;
  992.                     if (ptr_size > max_used_size)
  993.                         max_used_size = ptr_size;
  994.                     }
  995.                 
  996.                 hdr = (_mem_ptr_hdr_ptr)
  997.                         ( (char *)hdr + GET_PTR_SIZE(hdr) + sizeof(_mem_ptr_hdr) );
  998.                 }
  999.             
  1000.             if (num_free_hdrs == 0)
  1001.                 ave_free_size = (float)0.0;
  1002.             else
  1003.                 ave_free_size = (float)free_hdr_space / (float)num_free_hdrs;
  1004.             
  1005.             if (num_used_hdrs == 0)
  1006.                 ave_used_size = (float)0.0;
  1007.             else
  1008.                 ave_used_size = (float)used_hdr_space / (float)num_used_hdrs;
  1009.             
  1010.             if (num_used_hdrs == 0) {
  1011.                 frag_ratio = (float)num_free_hdrs / 2.0;
  1012.                 }
  1013.             else {
  1014.                 frag_ratio = (float)num_free_hdrs / (float)num_used_hdrs;
  1015.                 }
  1016.             
  1017.             fprintf(file, "\tBLOCK #%-4d Fragmentation Ratio %5.2f\n", i, frag_ratio);
  1018.             fprintf(file, "\t      #%-4d    Block Size %ld Ptr x%lx MaxFree %ld\n",
  1019.                     i, blk->size, blk->memory, blk->max_free);
  1020.             fprintf(file, "\t      #%-4d    Number free ptrs %d Number used ptrs %d\n",
  1021.                     i, num_free_hdrs, num_used_hdrs);
  1022.             fprintf(file, "\t      #%-4d    Free space %ld Used space %ld\n",
  1023.                     i, free_hdr_space, used_hdr_space);
  1024.             fprintf(file, "\t      #%-4d    Max free ptr %ld Max used ptr %ld\n",
  1025.                     i, max_free_size, max_used_size);
  1026.             fprintf(file, "\t      #%-4d    Ave free ptr size %5.1f Ave used ptr size %5.1f\n",
  1027.                     i, ave_free_size, ave_used_size);
  1028.  
  1029.             blk = blk->next;
  1030.             }
  1031.     }
  1032.  
  1033.  
  1034. list_pool_forest(file, with_data)
  1035. FILE    *file;
  1036. int        with_data;
  1037. {
  1038. _mem_pool_ptr        pool;
  1039. _mem_blk_ptr        blk;
  1040. _mem_ptr_hdr_ptr    hdr, limit;
  1041. int                    i, j;
  1042. extern char            temp_str[];
  1043.  
  1044.     if (file == (FILE *)0) {
  1045.         file = stdout;
  1046.         }
  1047.     
  1048.     pool = _mem_pool_forest;
  1049.     while (pool != (_mem_pool_ptr)0) {
  1050.         
  1051.         list_pool_stats(file, pool);
  1052.         
  1053.         blk = pool->blk_list;
  1054.         for (i=0; blk != (_mem_blk_ptr)0; i++) {
  1055.             fprintf(file, "   BLK #%05d ; @ x%lx ; blk_size %ld ; memory x%lx ; max_free %ld\n",
  1056.                     i, blk, blk->size, blk->memory, blk->max_free);
  1057.             fprintf(file, "   BLK          pool x%lx ; next blk x%lx\n", blk->pool, blk->next);
  1058.             
  1059.             hdr = (_mem_ptr_hdr_ptr) blk->memory;
  1060.             limit = (_mem_ptr_hdr_ptr) ((char *)blk->memory + blk->size);
  1061.             for (j=0; hdr && hdr < limit; j++) {
  1062.                 sprintf(temp_str, "      PTR #%d ; hdr x%lx ; nxt x%08lx ; size %ld ; flgs x%02x",
  1063.                         j, hdr, hdr->size, GET_PTR_SIZE(hdr), GET_PTR_FLAGS(hdr));
  1064.                 if (with_data)
  1065.                     hex_dump(file, temp_str,
  1066.                             (char *)((char *)hdr + sizeof(_mem_ptr_hdr)),
  1067.                             GET_PTR_SIZE(hdr));
  1068.                 else
  1069.                     fprintf(file, "%s\n", temp_str);
  1070.                 
  1071.                 hdr = (_mem_ptr_hdr_ptr)
  1072.                         ( (char *)hdr + GET_PTR_SIZE(hdr) + sizeof(_mem_ptr_hdr) );
  1073.                 }
  1074.             
  1075.             blk = blk->next;
  1076.             }
  1077.         
  1078.         pool = pool->next;
  1079.         }
  1080.     }
  1081.  
  1082. #define ROW_BYTES        16
  1083.  
  1084. hex_dump(output, title, ptr, bytes)
  1085. FILE    *output;
  1086. char    *title;
  1087. char    *ptr;
  1088. long    bytes;
  1089. {
  1090. int                rows, residue, i, j;
  1091. unsigned char    save_buf[ROW_BYTES+2];
  1092. unsigned char    hex_buf[4];
  1093. char            hex_chars[20];
  1094.     strcpy(hex_chars, "0123456789ABCDEF");
  1095.     
  1096.     fprintf(output, "\n%s - x%lX (%ld) bytes.\n", title, bytes, bytes);
  1097.     rows = bytes >> 4;
  1098.     residue = bytes & 0x0000000F;
  1099.     for (i=0; i<rows; i++) {
  1100.         fprintf(output, "%04.4X:", i * ROW_BYTES);
  1101.         for (j=0; j<ROW_BYTES; j++) {
  1102.             save_buf[j] = *ptr++;
  1103.             hex_buf[0] = hex_chars[(save_buf[j] >> 4) & 0x0F];
  1104.             hex_buf[1] = hex_chars[save_buf[j] & 0x0F];
  1105.             hex_buf[2] = '\0';
  1106.             fprintf(output, " %2.2s", hex_buf);
  1107.             if (save_buf[j] < 0x20 || save_buf[j] > 0xD9) save_buf[j] = '.';
  1108.             }
  1109.         save_buf[ROW_BYTES+1] = '\0';
  1110.         fprintf(output, "\t/* %16.16s */\n", save_buf);
  1111.         }
  1112.     if (residue) {
  1113.         fprintf(output, "%04.4X:", i * ROW_BYTES);
  1114.         for (j=0; j<residue; j++) {
  1115.             save_buf[j] = *ptr++;
  1116.             hex_buf[0] = hex_chars[(save_buf[j] >> 4) & 0x0F];
  1117.             hex_buf[1] = hex_chars[save_buf[j] & 0x0F];
  1118.             hex_buf[2] = '\0';
  1119.             fprintf(output, " %2.2s", hex_buf);
  1120.             if (save_buf[j] < 0x20 || save_buf[j] > 0xD9) save_buf[j] = '.';
  1121.             }
  1122.         for (/*j INHERITED*/; j<ROW_BYTES; j++) {
  1123.             save_buf[j] = ' ';
  1124.             fprintf(output, "   ");
  1125.             }
  1126.         save_buf[ROW_BYTES+1] = '\0';
  1127.         fprintf(output, "\t/* %16.16s */\n", save_buf);
  1128.         }
  1129.     }
  1130.  
  1131. #ifdef TESTING
  1132.  
  1133. main(argc, argv)
  1134. char    *argc;
  1135. char    *argv[];
  1136. {
  1137. int        i;
  1138. _mem_pool_ptr pool;
  1139. char    *ptr, *aptr[20];
  1140. char    input[128];
  1141. #pragma unused (argc, argv)
  1142.  
  1143.     printf("Debug level?\n");
  1144.     gets(input);
  1145.     if (input[0] == '\0' || input[0] == 'q')
  1146.         return 0;
  1147.     
  1148.     pool_malloc_debug_level = atoi(input);
  1149.     printf("Debug level set to %d\n", pool_malloc_debug_level);
  1150.     
  1151.     fprintf(stderr, "******************** START ********************\n");
  1152.     list_pool_forest(stderr, 0);
  1153.     
  1154.     printf("Allocating in default (system) pool...\n");
  1155.     for (i = 10 ; i < (10 * 1024) ; i += 128)
  1156.         if (malloc(i) == NULL)
  1157.             break;
  1158.     
  1159.     fprintf(stderr, "******************** ## 1 ## ********************\n");
  1160.     list_pool_forest(stderr, 0);
  1161.     
  1162.     printf("Allocating and Free-ing in default (system) pool...\n");
  1163.     for (i = 10 ; i < (10 * 1024) ; i += 128)
  1164.         if ((ptr = malloc(i)) != NULL)
  1165.             free(ptr);
  1166.         else
  1167.             break;
  1168.         
  1169.     fprintf(stderr, "******************** ## 2 ## ********************\n");
  1170.     list_pool_forest(stderr, 0);
  1171.     
  1172.     printf("Allocating and Free-ing again in default (system) pool...\n");
  1173.     for (i = 0 ; i < 20 ; i++)
  1174.         aptr[i] = NULL;
  1175.     for (i = 0 ; i < 20 ; i++) {
  1176.         aptr[i] = malloc(i * 128);
  1177.         if (aptr[i] == NULL)
  1178.             break;
  1179.         }
  1180.     for (i = 19 ; i >= 0 ; i--)
  1181.         if (aptr[i] != NULL) {
  1182.             free(aptr[i]);
  1183.             }
  1184.         
  1185.     fprintf(stderr, "******************** ## 3 ## ********************\n");
  1186.     list_pool_forest(stderr, 0);
  1187.     
  1188.     pool = new_malloc_pool ( 2001, (16 * 1024) );
  1189.     printf("new_malloc_pool ( 2001, %d ) returns x%lx\n", (16 * 1024), pool);
  1190.     if (pool) {
  1191.         set_default_pool ( 2001 );
  1192.         
  1193.         printf("Allocating in pool #2001...\n");
  1194.         for (i = 10 ; i < (10 * 1024) ; i += 128)
  1195.             if (malloc(i) == NULL)
  1196.                 break;
  1197.         }
  1198.  
  1199.     fprintf(stderr, "******************** ## 4 ## ********************\n");
  1200.     list_pool_forest(stderr, 0);
  1201.     
  1202.     printf("Free-ing memory in pool #2001...\n");
  1203.     free_pool_memory ( 2001 );
  1204.  
  1205.     fprintf(stderr, "******************** ## 5 ## ********************\n");
  1206.     list_pool_forest(stderr, 0);
  1207.     
  1208.     printf("Done.\n");
  1209.     }
  1210.  
  1211. #endif TESTING
  1212.  
  1213. #endif _PM_STATS
  1214.  
  1215. bzero(ptr, size)
  1216. register char *ptr;
  1217. register u_long size;
  1218. {
  1219.     while (size-- > 0) *ptr++ = '\0';
  1220.     }
  1221.